package com.imooc.security.demo.controller;

import com.imooc.security.demo.other.DeferredResultHolder;
import com.imooc.security.demo.other.MockQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.Random;
import java.util.concurrent.Callable;

/**
 * 异步处理请求
 * @author JackYang
 * @description:
 * @create: 2020/6/14 12:54
 */
@RestController
@RequestMapping("/async")
public class AsyncController {
    
    @Autowired
    private MockQueue mockQueue;
    @Autowired
    private DeferredResultHolder deferredResultHolder;
    
    private Logger logger= LoggerFactory.getLogger(getClass());
    
    /**
     *
     */
    @GetMapping("/order2")
    public DeferredResult<String> order2() throws Exception {
        logger.info("主线程开始执行");
        //产生随机数作为订单号
        String random = String.valueOf(new Random().nextInt(1000));
        mockQueue.setPlaceOrder(random);
        DeferredResult<String> deferredResult = new DeferredResult<>();
        //订单号与创建的副线程之间的的绑定
        deferredResultHolder.getMap().put(random,deferredResult);
        logger.info("主线程返回");
        return deferredResult;
    }
    
    /**
     * 传统方式
     */
    @GetMapping("/order")
    public String order() throws InterruptedException {
        logger.info("主线程开始执行");
        Thread.sleep(1500);
        logger.info("主线程返回");
        return "success";
    }
    
    /**
     * Callable方式提高并发量
     */
    @GetMapping("/orderCallable")
    public Callable<String> orderCallable() throws InterruptedException {
        logger.info("主线程开始执行");
        Callable<String> callable = () -> {
            logger.info("副线程开始执行");
            Thread.sleep(1500);
            logger.info("副线程返回");
            return "success";
        };
        logger.info("主线程返回");
        return callable;
    }
    

}
